<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>webAudio demo1</title>
    <script>
        setFontSize()
        window.onresize = function () { setFontSize() }
        function setFontSize() { document.getElementsByTagName('html')[0].style.fontSize = parseInt(document.documentElement.clientWidth) / 7.5 + 'px' }
    </script>
    <style>
        html,
        body {
            margin: 0;
            overflow: hidden;
            font-family: sans-serif;
            background: #13091B;
            height: 100%;
        }

        body {
            background: url(https://p1.music.126.net/gAmIGjlWnYXE_0O8LFp5-w==/109951164382001054.jpg) no-repeat;
            background-size: cover;
        }

        #canvas {
            position: fixed;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
        }

        audio {
            visibility: hidden;
        }

        #play-btn {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            color: #13091B;
            background: #007A99;
            display: block;
            width: 150px;
            height: 45px;
            line-height: 45px;
            font-size: 18px;
            cursor: pointer;
            border-radius: 4px;
            letter-spacing: 0.1em;
            z-index: 1;
            text-align: center;
            text-decoration: none;
        }
    </style>
</head>

<body>
    <div id="main">
        <div id="content">
            <canvas id="canvas"></canvas>
            <audio id="audio" controls
                src="//m8.music.126.net/21180815163607/04976f67866d4b4d11575ab418904467/ymusic/515a/5508/520b/f0cf47930abbbb0562c9ea61707c4c0b.mp3?infoId=92001"
                crossOrigin="anonymous"></audio>
            <a href="javascript:;" id="play-btn">PLAY</a>
        </div>
    </div>

    <script>
        var btn = document.getElementById("play-btn");
        var audio = document.getElementById("audio");

        btn.onclick = function () {
            btn.style.display = "none";

            audio.play();
            onLoadAudio();

        };

        function onLoadAudio() {
            var context = new (window.AudioContext || window.webkitAudioContext)();
            // 人们把人耳能够听到的振动频率称为音频，它的频率范围是从 20Hz - 20KHz，
            // 低于 20Hz 的频率称次声波，高于 20KHz 的频率称超声波。能够产生 20Hz - 20KHz 的振荡器就称为音频振荡器。
            // AnalyserNode 用于获取音频的频率数据（ FrequencyData ）和时域数据（ TimeDomainData ）。从而实现音频的可视化。
            var analyser = context.createAnalyser();
            analyser.fftSize = 512;

            // 将<audio>标签作为音频源
            var source = context.createMediaElementSource(audio);

            source.connect(analyser);
            analyser.connect(context.destination);

            // 获取频率数组
            var bufferLength = analyser.frequencyBinCount;
            var dataArray = new Uint8Array(bufferLength);

            var canvas = document.getElementById("canvas");
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;

            var ctx = canvas.getContext("2d");
            var WIDTH = canvas.width;
            var HEIGHT = canvas.height;

            var barWidth = WIDTH / bufferLength * 1.5;
            var barHeight;

            function renderFrame() {
                requestAnimationFrame(renderFrame);

                // 对已有的数组元素进行赋值
                analyser.getByteFrequencyData(dataArray);
                // 高精度
                // analyser.getFloatFrequencyData

                ctx.clearRect(0, 0, WIDTH, HEIGHT);

                for (var i = 0, x = 0; i < bufferLength; i++) {
                    // 根据频率映射一个矩形高度
                    barHeight = dataArray[i];

                    // 根据每个矩形高度映射一个背景色
                    // i / bufferLength 0-1
                    // var r = barHeight + 25 * (i / bufferLength);
                    var r = barHeight + 25 * (i / bufferLength);
                    var g = 250 * (i / bufferLength);
                    var b = 50;

                    // 绘制一个矩形，并填充背景色
                    ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")";
                    ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight);

                    x += barWidth + 2;
                }
            }

            renderFrame();
            // setInterval(renderFrame, 44);
        }
    </script>
</body>

</html>